{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Wavefront Error Optimization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "from optiland import optic, optimization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define a starting lens:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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b387fD4ffD4fduzYge985zvw+XxoaWnhsakCdXV1WLlyJQ4dOsS/Fwe1tbXhoosuKrvvwgsvLA0lrKbX/potcpqamrB69eppPwKBwKy+1oYNG7Bv376yVb2eeOIJJBKJCb8IND8CgQAuvfRSPPnkk6X7TNPEk08+iQ0bNji4Z1S0dOlStLa2lh2jVCqFXbt28RhVmBACN910Ex5++GH8/ve/x9KlS8sev/TSS+H3+8uOzcGDB3Hs2DEeG5uZpol8Ps9j4qArr7wS+/btw969e0sf69atw8c//vHSdR4b542MjODw4cNoa2vj34uDLr/88gmRBK+++ioWL14MoMpe+21d5sCl3njjDfHiiy+KO++8U8RiMfHiiy+KF198UaTTaSGEELqui66uLvHe975X7N27Vzz22GOiqalJ3HrrrQ7vubdt375dBINB8cADD4iXX35ZfO5znxN1dXVlq9xRZaXT6dLfAwBx9913ixdffFG88cYbQggh7rrrLlFXVyd+9atfiZdeeklcd911YunSpSKbzTq859524403imQyKZ5++mlx8uTJ0sfo6GjpOV/4whfEokWLxO9//3uxe/dusWHDBrFhwwYH99r7tm7dKnbs2CGOHDkiXnrpJbF161YhSZL43e9+J4TgMakmY1dXE4LHxgm33HKLePrpp8WRI0fEM888IzZt2iQaGxvF6dOnhRA8Jk55/vnnhc/nE1/72tfEa6+9Jn7605+KSCQifvKTn5SeUy2v/SxyZuGGG24QACZ8PPXUU6XnHD16VFx99dUiHA6LxsZGccsttwhN05zb6Rrx3e9+VyxatEgEAgFx2WWXieeee87pXaopTz311KR/GzfccIMQwlpK8p/+6Z9ES0uLCAaD4sorrxQHDx50dqdrwGTHBID40Y9+VHpONpsVX/ziF0V9fb2IRCLigx/8oDh58qRzO10DPv3pT4vFixeLQCAgmpqaxJVXXlkqcITgMakm44scHhv7XX/99aKtrU0EAgHR0dEhrr/+enHo0KHS4zwmznnkkUdEV1eXCAaDYvXq1eL73/9+2ePV8tovCSGEvb0jIiIiIiKiyqnZOTlERERERORNLHKIiIiIiMhTWOQQEREREZGnsMghIiIiIiJPYZFDRERERESewiKHiIiIiIg8hUUOERERERF5CoscIiIiIiLyFBY5RERERETkKSxyiIiIiIjIU1jkEBERERGRp7DIISIiIiIiT/n/KjZ7BfIgrTYAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 1000x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "lens = optic.Optic()\n",
    "\n",
    "# add surfaces\n",
    "lens.add_surface(index=0, radius=np.inf, thickness=np.inf)\n",
    "lens.add_surface(index=1, radius=50, thickness=3, material=\"SK16\")\n",
    "lens.add_surface(index=2, radius=-100, thickness=5)\n",
    "lens.add_surface(index=3, radius=-100, thickness=3, material=(\"F2\", \"schott\"))\n",
    "lens.add_surface(index=4, radius=50, thickness=5, is_stop=True)\n",
    "lens.add_surface(index=5, radius=50, thickness=3, material=\"SK16\")\n",
    "lens.add_surface(index=6, radius=-20, thickness=40)\n",
    "lens.add_surface(index=7)\n",
    "\n",
    "# set aperture\n",
    "lens.set_aperture(aperture_type=\"EPD\", value=10)\n",
    "\n",
    "# set fields\n",
    "lens.set_field_type(field_type=\"angle\")\n",
    "lens.add_field(y=0)\n",
    "\n",
    "# set wavelengths\n",
    "lens.add_wavelength(value=0.48)\n",
    "lens.add_wavelength(value=0.55, is_primary=True)\n",
    "lens.add_wavelength(value=0.65)\n",
    "\n",
    "lens.draw()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define optimization problem:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "problem = optimization.OptimizationProblem()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Add operands (targets for optimization):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "Add a wavefront error operand for all wavelengths.\n",
    "\n",
    "Use Gaussian quadrature distribution for the rays (see distribution documentation for\n",
    "more information).\n",
    "\"\"\"\n",
    "\n",
    "for wave in lens.wavelengths.get_wavelengths():\n",
    "    input_data = {\n",
    "        \"optic\": lens,\n",
    "        \"Hx\": 0,\n",
    "        \"Hy\": 0,\n",
    "        \"num_rays\": 3,\n",
    "        \"wavelength\": wave,\n",
    "        \"distribution\": \"gaussian_quad\",\n",
    "    }\n",
    "    problem.add_operand(\n",
    "        operand_type=\"OPD_difference\",\n",
    "        target=0,\n",
    "        weight=1,\n",
    "        input_data=input_data,\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define variables - let all radii vary (surface indices 1 through 6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "for surface_number in range(1, 7):\n",
    "    problem.add_variable(lens, \"radius\", surface_number=surface_number)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check initial merit function value and system properties:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "╒════╤════════════════════════╤═══════════════════╕\n",
      "│    │   Merit Function Value │   Improvement (%) │\n",
      "╞════╪════════════════════════╪═══════════════════╡\n",
      "│  0 │                  24631 │                 0 │\n",
      "╘════╧════════════════════════╧═══════════════════╛\n",
      "╒════╤════════════════╤══════════╤══════════╤══════════╤══════════╤════════════════════╕\n",
      "│    │ Operand Type   │   Target │   Weight │    Value │    Delta │   Contribution (%) │\n",
      "╞════╪════════════════╪══════════╪══════════╪══════════╪══════════╪════════════════════╡\n",
      "│  0 │ OPD difference │        0 │        1 │ 104.534  │ 104.534  │            44.3647 │\n",
      "│  1 │ OPD difference │        0 │        1 │  89.8916 │  89.8916 │            32.8063 │\n",
      "│  2 │ OPD difference │        0 │        1 │  74.9868 │  74.9868 │            22.8291 │\n",
      "╘════╧════════════════╧══════════╧══════════╧══════════╧══════════╧════════════════════╛\n",
      "╒════╤═════════════════╤═══════════╤═════════╤══════════════╤══════════════╕\n",
      "│    │ Variable Type   │   Surface │   Value │ Min. Bound   │ Max. Bound   │\n",
      "╞════╪═════════════════╪═══════════╪═════════╪══════════════╪══════════════╡\n",
      "│  0 │ radius          │         1 │      50 │              │              │\n",
      "│  1 │ radius          │         2 │    -100 │              │              │\n",
      "│  2 │ radius          │         3 │    -100 │              │              │\n",
      "│  3 │ radius          │         4 │      50 │              │              │\n",
      "│  4 │ radius          │         5 │      50 │              │              │\n",
      "│  5 │ radius          │         6 │     -20 │              │              │\n",
      "╘════╧═════════════════╧═══════════╧═════════╧══════════════╧══════════════╛\n"
     ]
    }
   ],
   "source": [
    "problem.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define optimizer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "optimizer = optimization.OptimizerGeneric(problem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Run optimization:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  message: CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH\n",
       "  success: True\n",
       "   status: 0\n",
       "      fun: 0.4929267697216927\n",
       "        x: [-5.850e-01 -1.977e+00 -2.011e+00 -4.529e-01 -4.369e-01\n",
       "            -2.186e+00]\n",
       "      nit: 9\n",
       "      jac: [ 1.326e-01  9.691e-02 -2.440e-01  4.657e-01  9.640e-02\n",
       "             4.481e-02]\n",
       "     nfev: 70\n",
       "     njev: 10\n",
       " hess_inv: <6x6 LbfgsInvHessProduct with dtype=float64>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "optimizer.optimize()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Print merit function value and system properties after optimization:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "╒════╤════════════════════════╤═══════════════════╕\n",
      "│    │   Merit Function Value │   Improvement (%) │\n",
      "╞════╪════════════════════════╪═══════════════════╡\n",
      "│  0 │               0.492927 │            99.998 │\n",
      "╘════╧════════════════════════╧═══════════════════╛\n",
      "╒════╤════════════════╤══════════╤══════════╤══════════╤══════════╤════════════════════╕\n",
      "│    │ Operand Type   │   Target │   Weight │    Value │    Delta │   Contribution (%) │\n",
      "╞════╪════════════════╪══════════╪══════════╪══════════╪══════════╪════════════════════╡\n",
      "│  0 │ OPD difference │        0 │        1 │ 0.485152 │ 0.485152 │           47.7499  │\n",
      "│  1 │ OPD difference │        0 │        1 │ 0.155018 │ 0.155018 │            4.87508 │\n",
      "│  2 │ OPD difference │        0 │        1 │ 0.483243 │ 0.483243 │           47.375   │\n",
      "╘════╧════════════════╧══════════╧══════════╧══════════╧══════════╧════════════════════╛\n",
      "╒════╤═════════════════╤═══════════╤═══════════╤══════════════╤══════════════╕\n",
      "│    │ Variable Type   │   Surface │     Value │ Min. Bound   │ Max. Bound   │\n",
      "╞════╪═════════════════╪═══════════╪═══════════╪══════════════╪══════════════╡\n",
      "│  0 │ radius          │         1 │   41.5009 │              │              │\n",
      "│  1 │ radius          │         2 │  -97.652  │              │              │\n",
      "│  2 │ radius          │         3 │ -101.134  │              │              │\n",
      "│  3 │ radius          │         4 │   54.7111 │              │              │\n",
      "│  4 │ radius          │         5 │   56.3141 │              │              │\n",
      "│  5 │ radius          │         6 │ -118.584  │              │              │\n",
      "╘════╧═════════════════╧═══════════╧═══════════╧══════════════╧══════════════╛\n"
     ]
    }
   ],
   "source": [
    "problem.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Draw final lens:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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0Ufxk5/8BNu3b8fRo0fxmc98JsKjjr+VK1fi3nvvxa5du/Diiy/iox/9KD75yU9i7969AHhO2sELL7yAv/mbv8HFF19cs5znJhoXXHABjh07Fj7+67/+K1zHcxKNU6dO4aqrroKmafj5z3+O1157DX/1V3+F3t7ecJu2+dsvaN6+//3vi+7u7inL//3f/13IsiyGh4fDZQ888IDo6uoSpmm28AgXlyuvvFLcfPPN4XvXdcXy5cvFtm3bIjyqxQuAeOSRR8L3nueJoaEh8c1vfjNcdvr0aWEYhvjHf/zHCI5w8RoZGREAxPbt24UQ/nnQNE385Cc/CbfZt2+fACB27NgR1WEuSr29veLv/u7veE7aQD6fF+eee6544oknxIc//GHx1a9+VQjB35eo3HXXXeKSSy6Zdh3PSXT+9E//VHzwgx+ccX07/e3nSE4D7NixAxdddBEGBwfDZddddx1yuVz4P3TUWJZlYdeuXbj22mvDZbIs49prr8WOHTsiPDIKHDp0CMPDwzXnqLu7G5s3b+Y5arHx8XEAwJIlSwAAu3btgm3bNedm48aNWL16Nc9Ni7iui4cffhgTExPYsmULz0kbuPnmm3H99dfXnAOAvy9R2r9/P5YvX47169fj85//PN555x0APCdR+ulPf4pNmzbhs5/9LAYGBnDppZfib//2b8P17fS3nyGnAYaHh2sCDoDw/fDwcBSHFHtjY2NwXXfa7zu/5+0hOA88R9HyPA9f+9rXcNVVV+HCCy8E4J8bXden9Bjy3DTfq6++ikwmA8Mw8OUvfxmPPPIIzj//fJ6TiD388MN46aWXsG3btinreG6isXnzZjz00EN47LHH8MADD+DQoUO4+uqrkc/neU4i9NZbb+GBBx7Aueeei8cffxw33XQTvvKVr+AHP/gBgPb626+2dG9tZOvWrfjGN74x6zb79u2raXIjIuo0N998M/bs2VNTy07R2bBhA3bv3o3x8XH80z/9E2688UZs37496sNa1N5991189atfxRNPPIFEIhH14VDFxz/+8fD1xRdfjM2bN2PNmjX48Y9/jGQyGeGRLW6e52HTpk34i7/4CwDApZdeij179uDBBx/EjTfeGPHR1Vq0Izm333479u3bN+tj/fr18/pcQ0NDU2b0CN4PDQ01/NgJ6Ovrg6Io037f+T1vD8F54DmKzi233IKf/exnePrpp7Fy5cpw+dDQECzLwunTp2u257lpPl3Xcc455+Dyyy/Htm3bcMkll+Cv//qveU4itGvXLoyMjOCyyy6DqqpQVRXbt2/Ht7/9baiqisHBQZ6bNtDT04PzzjsPBw4c4O9LhJYtW4bzzz+/Ztl73/vesJSwnf72L9qQ09/fj40bN8760HV9Xp9ry5YtePXVV2tm9XriiSfQ1dU15QeBGkPXdVx++eV48sknw2We5+HJJ5/Eli1bIjwyCqxbtw5DQ0M15yiXy2Hnzp08R00mhMAtt9yCRx55BE899RTWrVtXs/7yyy+Hpmk15+aNN97AO++8w3PTYp7nwTRNnpMIXXPNNXj11Vexe/fu8LFp0yZ8/vOfD1/z3ESvUCjg4MGDWLZsGX9fInTVVVdNuSXBm2++iTVr1gBos7/9LZ3moEO9/fbb4uWXXxb33HOPyGQy4uWXXxYvv/yyyOfzQgghHMcRF154ofjYxz4mdu/eLR577DHR398v7rjjjoiPPN4efvhhYRiGeOihh8Rrr70mfv/3f1/09PTUzHJHzZXP58PfBwDivvvuEy+//LJ4++23hRBC3HvvvaKnp0f867/+q3jllVfEJz/5SbFu3TpRKpUiPvJ4u+mmm0R3d7d45plnxLFjx8JHsVgMt/nyl78sVq9eLZ566inx4osvii1btogtW7ZEeNTxt3XrVrF9+3Zx6NAh8corr4itW7cKSZLEL37xCyEEz0k7qZ5dTQiemyjcfvvt4plnnhGHDh0Sv/zlL8W1114r+vr6xMjIiBCC5yQqzz//vFBVVXz9618X+/fvF3//938vUqmU+OEPfxhu0y5/+xly5uHGG28UAKY8nn766XCbX//61+LjH/+4SCaToq+vT9x+++3Ctu3oDnqR+M53viNWr14tdF0XV155pXjuueeiPqRF5emnn572d+PGG28UQvhTSf7Zn/2ZGBwcFIZhiGuuuUa88cYb0R70IjDdOQEgvv/974fblEol8Yd/+Ieit7dXpFIp8elPf1ocO3YsuoNeBH73d39XrFmzRui6Lvr7+8U111wTBhwheE7aSX3I4blpvRtuuEEsW7ZM6LouVqxYIW644QZx4MCBcD3PSXQeffRRceGFFwrDMMTGjRvFd7/73Zr17fK3XxJCiNaOHRERERERETXPou3JISIiIiKieGLIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWGHIISIiIiKiWPn/AbKhzXoxFhyBAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1000x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "lens.draw(num_rays=5)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
